package com.cmc.cloud.cmclink.doc.util;

import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * PDF合并工具类
 *
 * @author 集运管理员
 */
public class PdfMerger {
    /**
     * 合并多个PDF文件（适用于大型文件）
     * @param inputFiles 输入PDF文件路径数组
     * @param outputFile 输出PDF文件路径
     * @param useTempFile 是否使用临时文件避免内存溢出
     * @param tempDir 临时文件目录，为null时使用系统默认目录
     */
    public static void mergeLargePdfs(String[] inputFiles, String outputFile,
                                      boolean useTempFile, String tempDir) throws IOException {
        PDFMergerUtility merger = new PDFMergerUtility();
        List<File> tempFiles = new ArrayList<>();

        try {
            // 设置输出文件路径
            merger.setDestinationFileName(outputFile);

            // 添加要合并的PDF文件
            for (String inputFile : inputFiles) {
                File file = new File(inputFile);
                if (file.exists() && file.isFile()) {
                    merger.addSource(file);
                } else {
                    System.err.println("文件不存在或不是文件: " + inputFile);
                }
            }

            // 根据文件大小选择内存管理策略
            if (useTempFile) {
                // 使用临时文件模式，适合处理大型PDF
                if (tempDir != null) {
                    File tempDirectory = new File(tempDir);
                    if (!tempDirectory.exists()) {
                        tempDirectory.mkdirs();
                    }
                    // 创建自定义临时文件设置
                    MemoryUsageSetting memorySetting = MemoryUsageSetting.setupTempFileOnly();
                    memorySetting.setTempDir(tempDirectory);
                    merger.mergeDocuments(memorySetting);
                } else {
                    merger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
                }
            } else {
                // 仅内存模式，适合中小型PDF
                merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
            }

        } finally {
            // 清理临时文件
            cleanupTempFiles(tempFiles);
        }
    }

    /**
     * 合并多个PDF文件（适用于大型文件）
     * @param inputFiles 输入PDF文件路径数组
     * @param outputFile 输出PDF文件路径
     * @param useTempFile 是否使用临时文件避免内存溢出
     * @param tempDir 临时文件目录，为null时使用系统默认目录
     */
    public static void mergeLargePdfs(List<File> inputFiles, String outputFile,
                                      boolean useTempFile, String tempDir) throws IOException {
        PDFMergerUtility merger = new PDFMergerUtility();
        List<File> tempFiles = new ArrayList<>();

        try {
            // 设置输出文件路径
            merger.setDestinationFileName(outputFile);

            // 添加要合并的PDF文件
            for (File inputFile : inputFiles) {
                if (inputFile.exists() && inputFile.isFile()) {
                    merger.addSource(inputFile);
                } else {
                    System.err.println("文件不存在或不是文件: " + inputFile);
                }
            }

            // 根据文件大小选择内存管理策略
            if (useTempFile) {
                // 使用临时文件模式，适合处理大型PDF
                if (tempDir != null) {
                    File tempDirectory = new File(tempDir);
                    if (!tempDirectory.exists()) {
                        tempDirectory.mkdirs();
                    }
                    // 创建自定义临时文件设置
                    MemoryUsageSetting memorySetting = MemoryUsageSetting.setupTempFileOnly();
                    memorySetting.setTempDir(tempDirectory);
                    merger.mergeDocuments(memorySetting);
                } else {
                    merger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
                }
            } else {
                // 仅内存模式，适合中小型PDF
                merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
            }

        } finally {
            // 清理临时文件
            cleanupTempFiles(tempFiles);
        }
    }

    /**
     * 安全合并PDF文件，自动检测文件大小并选择合适的内存策略
     */
    public static void safeMergePdfs(String[] inputFiles, String outputFile, String tempDir) throws IOException {
        long totalSize = 0;

        // 计算所有文件总大小
        for (String inputFile : inputFiles) {
            File file = new File(inputFile);
            if (file.exists()) {
                totalSize += file.length();
            }
        }

        // 如果总文件大小超过100MB，使用临时文件模式
        boolean useTempFile = totalSize > 100 * 1024 * 1024;

        System.out.println("检测到总文件大小: " + (totalSize / (1024 * 1024)) + "MB");
        System.out.println("使用内存模式: " + (useTempFile ? "临时文件" : "仅内存"));

        mergeLargePdfs(inputFiles, outputFile, useTempFile, tempDir);
    }

    /**
     * 安全合并PDF文件，自动检测文件大小并选择合适的内存策略
     */
    public static void safeMergePdfs(List<File> inputFiles, String outputFile, String tempDir) throws IOException {
        long totalSize = 0;

        // 计算所有文件总大小
        for (File inputFile : inputFiles) {
            if (inputFile.exists()) {
                totalSize += inputFile.length();
            }
        }

        // 如果总文件大小超过100MB，使用临时文件模式
        boolean useTempFile = totalSize > 100 * 1024 * 1024;

        System.out.println("检测到总文件大小: " + (totalSize / (1024 * 1024)) + "MB");
        System.out.println("使用内存模式: " + (useTempFile ? "临时文件" : "仅内存"));

        mergeLargePdfs(inputFiles, outputFile, useTempFile, tempDir);
    }

    /**
     * 手动创建并管理临时文件
     */
    public static File createManagedTempFile(String prefix, String suffix, String directory) throws IOException {
        File tempFile;
        if (directory != null) {
            File dir = new File(directory);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            tempFile = File.createTempFile(prefix, suffix, dir);
        } else {
            tempFile = File.createTempFile(prefix, suffix);
        }

        // 设置JVM退出时删除
        tempFile.deleteOnExit();
        return tempFile;
    }

    /**
     * 清理临时文件
     */
    private static void cleanupTempFiles(List<File> tempFiles) {
        for (File tempFile : tempFiles) {
            if (tempFile.exists()) {
                boolean deleted = tempFile.delete();
                if (deleted) {
                    System.out.println("已删除临时文件: " + tempFile.getAbsolutePath());
                } else {
                    System.err.println("无法删除临时文件: " + tempFile.getAbsolutePath());
                    // 如果立即删除失败，设置JVM退出时删除
                    tempFile.deleteOnExit();
                }
            }
        }
        tempFiles.clear();
    }

    /**
     * 扫描并删除指定目录中的临时文件
     */
    public static void cleanupTempDirectory(String directoryPath, String filePattern) throws IOException {
        File directory = new File(directoryPath);
        if (directory.exists() && directory.isDirectory()) {
            File[] files = directory.listFiles((dir, name) -> name.matches(filePattern));
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        boolean deleted = file.delete();
                        if (deleted) {
                            System.out.println("已清理临时文件: " + file.getName());
                        }
                    }
                }
            }
        }
    }
    public static void main(String[] args) {
        try {
            // 示例：合并多个PDF文件
            String[] pdfFiles = {
                    "document1.pdf",
                    "document2.pdf",
                    "document3.pdf"
            };

            String outputPath = "merged_document.pdf";
            String tempDirectory = "temp_pdf_files";

            // 创建临时目录
            File tempDir = new File(tempDirectory);
            if (!tempDir.exists()) {
                tempDir.mkdirs();
            }

            // 使用安全合并方法
            safeMergePdfs(pdfFiles, outputPath, tempDirectory);

            System.out.println("PDF文件合并成功！输出文件: " + outputPath);

            // 程序退出前清理临时目录
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                try {
                    cleanupTempDirectory(tempDirectory, ".*\\.tmp");
                    if (tempDir.exists()) {
                        tempDir.delete();
                        System.out.println("已删除临时目录: " + tempDirectory);
                    }
                } catch (IOException e) {
                    System.err.println("清理临时目录时出错: " + e.getMessage());
                }
            }));

        } catch (IOException e) {
            System.err.println("PDF合并过程中出现错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
